package cpdt.testartifact;

import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.IOException;
import java.net.URL;

/**
 * Helper class for XML validation against a schema
 */
public class ValidationHelper {

    private final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

    private final Validator validator;

    /**
     * Creates a ValidationHelper that will use the specified schema for XML validation
     *
     * @param resource The resource to read the schema from. If the schema is a (resource) file in the classpath, you
     *                 probably want to use getClass().getResource(location)
     * @throws IllegalArgumentException if the provided stream does not contain a valid schema or if the resource could
     *                                  not be read
     */
    public ValidationHelper(URL resource) {
        final Source schemaSource;
        try {
            schemaSource = new StreamSource(resource.openStream());
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
        // this is necessary to allow includes of relative schemaLocations in the schema
        schemaSource.setSystemId(resource.toString());

        final Schema schema;
        try {
            schema = schemaFactory.newSchema(schemaSource);
        } catch (SAXException e) {
            throw new IllegalArgumentException(e);
        }
        validator = schema.newValidator();
    }

    public void validate(Source xml) throws IOException, SAXException {
        validator.validate(xml);
    }
}
